package com.master.equipment.netty.server;

import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.master.equipment.entity.Aep;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {

	// 管理一个全局map，保存连接进服务端的通道数量
	public static Map<String, ChannelHandlerContext> map = new HashMap<String, ChannelHandlerContext>();

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) {
		log.info("--------------接收到的数据complete----------------------");
		ctx.flush();
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		log.info("接收到的数据：{}", msg);
//		//校验
		if (ctx == null) {
			log.error("通道不存在");
			return;
		}
		if (msg == null) {
			System.out.println("服务端响应空的消息");
			return;
		}
		log.info("---channelRead 客户端---{}----{}", ctx.channel().remoteAddress(), ctx.channel().id());
		
		//保存
		String message = msg.toString();
		
		Aep aep = dataChange(message);
//		log.info("接收到的数据Aep：{}", aep);
		log.info("接收到的数据Aep：{}", JSONObject.toJSONString(aep));
		
		String dataType = aep.getDataType();
		log.info("-------------------------------dataType----{}------------------------------", dataType);
		
		if(StrUtil.equals(dataType, "01") ){
			log.info("数据处理01：{}");
			String replay = "0E00100103010001007F";
			this.channelWrite(ctx, replay);
		}else if(StrUtil.equals(dataType, "06")  ){
			String replay = "0E00100603060001007F";
			this.channelWrite(ctx, replay);
		}else if(StrUtil.equals(dataType, "02")  ){
			String replay = "0E00100203020001007F";
			this.channelWrite(ctx, replay);
		}else if(StrUtil.equals(dataType, "08")  ){

			log.info("数据处理08");
			String replay = "0E00100803080001007F";
			this.channelWrite(ctx, replay);

		}else {
			log.info("数据处理绑定手机号");
			
			String replay ="0E0001073A070D020B166028762970000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001007F";
			
			this.channelWrite(ctx, replay);
		}
		
		putChannelMap(ctx);
	}

	private Aep dataChange(String message) {
    	String header = StrUtil.sub(message.toString(), 0, 4);
		String version = StrUtil.sub(message.toString(), 4, 6);
		String dataType = StrUtil.sub(message.toString(), 6, 8);
		String dataLen = StrUtil.sub(message.toString(), 8, 10);
		String deviceType = StrUtil.sub(message.toString(), 10, 12);
		String dataTypeValue = StrUtil.sub(message.toString(), 12, 14);
		String deviceNo = StrUtil.sub(message.toString(), 14, 44);
		String imsi = StrUtil.sub(message.toString(), 44, 74);
		String iccid = StrUtil.sub(message.toString(), 74, 114);
		
		String cellVoltage = StrUtil.sub(message.toString(), 114, 116);
		String signal = StrUtil.sub(message.toString(), 116, 118);
		String electricQuantity = StrUtil.sub(message.toString(), 118, 120);
		
		String deviceVersion = StrUtil.sub(message.toString(), 120, 124);
		String backUp = StrUtil.sub(message.toString(), 124, 128);
		String frameNumber = StrUtil.sub(message.toString(), 128, 130);
		String verify = StrUtil.sub(message.toString(), 130, 132);
		String end = StrUtil.sub(message.toString(), 132, 134);
		
		Aep aep = new Aep();
		aep.setHeader(header);
		aep.setVersion(version);
		aep.setDataType(dataType);
		aep.setDataLen(dataLen);
		aep.setDeviceType(deviceType);
		aep.setDataTypeValue(dataTypeValue);
		aep.setDeviceNo(deviceNo);
		aep.setImsi(imsi);
		aep.setIccid(iccid);
		aep.setCellVoltage(cellVoltage);
		aep.setSignal(signal);
		aep.setElectricQuantity(electricQuantity);
		aep.setDeviceVersion(deviceVersion);
		aep.setBackUp(backUp);
		aep.setFrameNumber(frameNumber);
		aep.setVerify(verify);
		aep.setEnd(end);
		
		return aep;
	}
	
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, String message) throws Exception {
		log.info("--------------接收到的数据22222222222----------------------"+message);
		this.channelWrite(ctx, message);
	}

	public void channelWrite(ChannelHandlerContext ctx, String message) throws Exception {
		log.info("--------------回复服务器----------------------"+message);
		writeToClient(ctx,message);
//		String[] msgArr = message.split("\\*");
//		if (msgArr.length != 4) {
//			return;
//		}
//		// 设备厂商
//		String manufacturer = msgArr[0];
//		// 设备编号
//		String equipmentNo = msgArr[1];
//		String[] contentArr = msgArr[3].split(",");
//		//将客户端的信息直接返回写入ctx
//		if (StringUtils.equalsIgnoreCase(contentArr[0], "KA")) {
//			
//		} else if (StringUtils.equalsIgnoreCase(contentArr[0], "LGZONE")) {
//			log.info("--------------回复服务器时间----------------------");
//			// 平台回复：[XT*YYYYYYYYYYYYYYY*LEN*LGZONE,时区,时间,日期]
//			// 实例: [XT*1234567890*001D*LGZONE,+8,08:00:00,2016-01-12]
//			// 实例表示：东八区，上午 8 点整
//			// 说明：当设备开机建立链接时，需要获取当前最新的时间。服务器将最新的时间回复给终端。 西时区用
//			// “-”表示，时间用 24 小时制。
//			Date date = new Date();
//			writeToClient(ctx, manufacturer, equipmentNo,
//					"LGZONE,+8," + DateUtil.format(date, DatePattern.NORM_TIME_PATTERN) + "," + DateUtil.format(date, DatePattern.NORM_DATE_PATTERN));
//		} else if (StringUtils.equalsIgnoreCase(contentArr[0], "SOSQ")) {
//			log.info("--------------回复服务器时间----------------------");
//			
//		} else if (StringUtils.startsWith(contentArr[0], "UD")) {
//			
//			
//		} else if (StringUtils.startsWith(contentArr[0], "AL")) {
//		
//		} else if (StringUtils.equalsIgnoreCase(contentArr[0], "heart")) {
//			
//			writeToClient(ctx, manufacturer, equipmentNo, "heart");
//		} else if (StringUtils.equalsIgnoreCase(contentArr[0], "temp")) {
//			
//
//			writeToClient(ctx, manufacturer, equipmentNo, "temp");
//		} else if (StringUtils.equalsIgnoreCase(contentArr[0], "blood")) {
//		
//			writeToClient(ctx, manufacturer, equipmentNo, "blood");
//		} else if (StringUtils.equalsIgnoreCase(contentArr[0], "oxygen")) {
//		
//			writeToClient(ctx, manufacturer, equipmentNo, "oxygen");
//		}
	}


	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		putChannelMap(ctx);
	}


	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		log.info("---客户端连接---, {}", ctx.channel().remoteAddress());
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		log.info("---客户端连接---, {} 关闭", ctx.channel().remoteAddress());
		//删除
		removeChannelMap(ctx);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		log.info("----------------服务异常关闭----------------");
		removeChannelMap(ctx);
		//有异常就关闭连接
		cause.printStackTrace();
		ctx.close();
	}

	private void putChannelMap(ChannelHandlerContext ctx) {
		log.info("----写入-----{}", ctx.channel().remoteAddress().toString());
		map.put(ctx.channel().remoteAddress().toString(), ctx);
	}

	private void removeChannelMap(ChannelHandlerContext ctx) {
		for (String key : map.keySet()) {
			if (map.get(key) != null && map.get(key).equals(ctx.channel().remoteAddress().toString())) {
				map.remove(key);
			}
		}
	}

	/**
	 * 将数字转化为需要的16进制内容
	 *
	 * @param number
	 * @return
	 */
	private String toHex(int number) {
		String hex = HexUtil.toHex(number);
		if (hex.length() == 1) {
			return "000" + hex;
		} else if (hex.length() == 2) {
			return "00" + hex;
		} else if (hex.length() == 3) {
			return "0" + hex;
		} else {
			return hex;
		}
	}

	/**
	 * 16进制转为2进制
	 *
	 * @param hexString
	 * @return
	 */
	private static String hexToBinary(String hexString) {
		int sint = Integer.valueOf(hexString, 16);
		//十进制在转换成二进制的字符串形式输出!
		if (sint == 0) {
			return "0000";
		}
		String s = Integer.toBinaryString(sint);
		if (s.length() == 1) {
			return "000" + s;
		} else if (s.length() == 2) {
			return "00" + s;
		} else if (s.length() == 3) {
			return "0" + s;
		} else {
			return s;
		}
	}

	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < "00010009".length(); i++) {
			sb.append(hexToBinary("00010009".substring(i, i + 1)));
		}
		System.out.println(sb.substring(15, 16));


		String s = "SOS,18581869561,";
		System.out.println(s.substring(0, s.length() - 1));

//		System.out.println(URLEncodeUtil.encode("邹颖"));
	}

	/**
	 * 给客户端写入内容
	 *
	 * @param ctx
	 * @param manufacturer
	 * @param equipmentNo
	 * @param content
	 */
	private void writeToClient(ChannelHandlerContext ctx,String content) {
//		log.info("发送内容：{}", content);
//		// 写入内容
//		ctx.write(content);
//		//刷新缓存区
//		ctx.flush();
		
		 //Netty需要用ByteBuf传输
	       ByteBuf bufff = Unpooled.buffer();
	       //对接需要16进制
	       bufff.writeBytes(this.hexString2Bytes(content));
	       ctx.writeAndFlush(bufff);
		
	}

	
	public static byte[] hexString2Bytes(String src) {

        int l = src.length() / 2;

        byte[] ret = new byte[l];

        for (int i = 0; i < l; i++) {

            ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();

        }

        return ret;

    }


public static String bytesToHexString(byte[] src) {
    StringBuilder stringBuilder = new StringBuilder("");
    if (src == null || src.length <= 0) {
        return null;
    }
    for (int i = 0; i < src.length; i++) {
        int v = src[i] & 0xFF;
        String hv = Integer.toHexString(v);
        if (hv.length() < 2) {
            stringBuilder.append(0);
        }
        stringBuilder.append(hv);
    }
    return stringBuilder.toString();
}

}
